package com.github.jspxnet.worktask.core.node;


import com.github.jspxnet.utils.BeanUtil;
import com.github.jspxnet.utils.ObjectUtil;
import com.github.jspxnet.worktask.core.NodeAction;
import com.github.jspxnet.worktask.dao.ConfWorkFlowDAO;
import com.github.jspxnet.worktask.dao.RuntimeServiceDAO;
import com.github.jspxnet.worktask.dao.UserAdapterDAO;
import com.github.jspxnet.worktask.model.enums.FlowNodeEnumType;
import com.github.jspxnet.worktask.model.enums.GatewayEnumType;
import com.github.jspxnet.worktask.model.enums.WorkTaskEnumType;
import com.github.jspxnet.worktask.model.param.WorkTaskParam;
import com.github.jspxnet.worktask.table.ConfFlowNode;
import com.github.jspxnet.worktask.table.WorkTask;
import lombok.Data;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 执行当前节点动作,然后传到下一节点
 */
@Data
public abstract class BaseNodeAction implements NodeAction {
    protected ConfWorkFlowDAO confWorkFlowDAO;

    protected RuntimeServiceDAO runtimeServiceDAO;

    protected UserAdapterDAO userAdapterDAO;

    //当前变量
    protected WorkTask currentWorkTask;
    //当前节点
    protected ConfFlowNode currentConfFlowNode;
    //下一步节点
    //protected List<ConfFlowNode> nextNodeList;
    //进入参数
    protected WorkTaskParam workTaskParam;

    protected Map<String, Object> variables;


    public void inNextNode() throws Exception {
        //如果有后边的节点继续 begin
        int endNode = runtimeServiceDAO.isFlowFinished(ObjectUtil.getMap(currentWorkTask));
        if (endNode>0)
        {
            return;
        }



        List<ConfFlowNode> nextNodeList = confWorkFlowDAO.getNextList(currentWorkTask.getFlowNo(), currentWorkTask.getNamespace(), currentWorkTask.getNodeId());
        //如果有后边的节点继续 end
        if (ObjectUtil.isEmpty(nextNodeList))
        {
            ConfFlowNode confFlowNode = confWorkFlowDAO.getConfFlowNode(currentWorkTask.getFlowNo(), currentWorkTask.getNamespace(),currentConfFlowNode.getJoinNodeId());
            if (!userAdapterDAO.isAuthority(confFlowNode, workTaskParam.getUserId())) {
                return;
            }
            WorkTask workTask = BeanUtil.copy(workTaskParam, WorkTask.class);
            workTask.setNodeId(confFlowNode.getNodeId());
            workTask.setFlowNodeType(confFlowNode.getFlowNodeType());
            workTask.setNamespace(confFlowNode.getNamespace());
            workTask.setFlowNo(confFlowNode.getFlowNo());
            workTask.setCreateDate(new Date());
            workTask.setFlowNodeType(FlowNodeEnumType.END.getValue());
            workTask.setWorkTaskType(WorkTaskEnumType.JOIN.getValue());
            workTask.setUsers(workTaskParam.getUsers());
            workTask.setId(0);

            if (FlowNodeEnumType.GATEWAY.getValue()==confFlowNode.getFlowNodeType()&&GatewayEnumType.JOIN.getValue()==confFlowNode.getGatWayType())
            {
                List<ConfFlowNode>  joinList = confWorkFlowDAO.getJoinConfFlowNode(currentWorkTask.getFlowNo(),currentWorkTask.getNamespace(),confFlowNode.getNodeId());
                List<String> joinNodeList = BeanUtil.copyFieldList(joinList,"nodeId");
                List<WorkTask> taskJoinNodeList = runtimeServiceDAO.getJoinExeNodeList(currentWorkTask.getFlowNo(),currentWorkTask.getNamespace(),currentWorkTask.getDocumentNo(),joinNodeList);
                List<String> taskNodeList = BeanUtil.copyFieldList(taskJoinNodeList,"nodeId");
                if (joinList.size()==taskNodeList.size() && runtimeServiceDAO.save(workTask)>=0)
                {
                        currentWorkTask= workTask;
                }
            } else
            {
                if (runtimeServiceDAO.save(workTask)>=0)
                {
                    currentWorkTask= workTask;
                }
            }


        } else {
            for (ConfFlowNode confFlowNode : nextNodeList) {
                if (FlowNodeEnumType.END.getValue()==confFlowNode.getFlowNodeType())
                {
                    return;
                } else
                if (GatewayEnumType.JOIN.getValue()!=confFlowNode.getGatWayType())
                {
                    WorkTask workTask = BeanUtil.copy(workTaskParam, WorkTask.class);
                    workTask.setNodeId(confFlowNode.getNodeId());
                    workTask.setFlowNodeType(confFlowNode.getFlowNodeType());
                    workTask.setNamespace(confFlowNode.getNamespace());
                    workTask.setFlowNo(confFlowNode.getFlowNo());
                    workTask.setCreateDate(new Date());
                    workTask.setUsers(workTaskParam.getUsers());
                    workTask.setId(0);
                    if (runtimeServiceDAO.save(workTask)>0)
                    {
                        currentWorkTask = workTask;
                    }
                }
                else
                {
                    BaseNodeAction baseNodeAction = new JoinNodeAction();
                    baseNodeAction.setRuntimeServiceDAO(runtimeServiceDAO);
                    baseNodeAction.setConfWorkFlowDAO(confWorkFlowDAO);
                    baseNodeAction.setUserAdapterDAO(userAdapterDAO);
                    baseNodeAction.setCurrentConfFlowNode(currentConfFlowNode);
                    baseNodeAction.setWorkTaskParam(workTaskParam);
                    baseNodeAction.setVariables(variables);
                    baseNodeAction.execute();
                }
            }
        }

        List<WorkTask> workTaskList = runtimeServiceDAO.getWorkTaskList(currentWorkTask.getFlowNo(), currentWorkTask.getNamespace(),currentWorkTask.getDocumentNo());
        for (WorkTask workTask:workTaskList)
        {
            if (workTask==null)
            {
                continue;
            }
            if (FlowNodeEnumType.END.getValue()==workTask.getFlowNodeType())
            {
                continue;
            }
            if (FlowNodeEnumType.START.getValue()==workTask.getFlowNodeType())
            {
                return;
            }
           if (FlowNodeEnumType.GATEWAY.getValue()==workTask.getFlowNodeType())
           {
               currentConfFlowNode = confWorkFlowDAO.getConfFlowNode(currentWorkTask.getFlowNo(), currentWorkTask.getNamespace(), currentWorkTask.getNodeId());
               currentWorkTask = workTask;
               inNextNode();
           }
        }
    }

    /**
     * 标识当前节点完成,如果下一个节点是结束,那么就结束流程
     */
    public void finishNode() {
        try {
            List<ConfFlowNode>  list = confWorkFlowDAO.getNextList(currentWorkTask.getFlowNo(),currentWorkTask.getNamespace(),currentWorkTask.getNodeId());
            if (ObjectUtil.isEmpty(list))
            {
                return;
            }
            if (list.size()==1)
            {
                ConfFlowNode nextConfFlowNode = list.get(0);
                if (nextConfFlowNode==null || FlowNodeEnumType.END.getValue()!=nextConfFlowNode.getFlowNodeType())
                {
                    return;
                }
                WorkTask endWorkTask = BeanUtil.copy(nextConfFlowNode,WorkTask.class);
                try {
                    endWorkTask.setFlowNodeType(FlowNodeEnumType.END.getValue());
                    endWorkTask.setDocumentNo(currentWorkTask.getDocumentNo());
                    endWorkTask.setUsers(workTaskParam.getUsers());
                    endWorkTask.setCreateDate(new Date());
                    endWorkTask.setId(0);
                    runtimeServiceDAO.save(endWorkTask);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }



}
